package com.engine.salary.wrapper;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveTaxAgentFormDTO;
import com.engine.salary.entity.salaryarchive.dto.SingleTaxAgentAdjustRecordListDTO;
import com.engine.salary.entity.salaryarchive.dto.TaxAgentAdjustRecordListDTO;
import com.engine.salary.entity.salaryarchive.param.SalaryArchiveTaxAgentSaveParam;
import com.engine.salary.entity.salaryarchive.param.SingleTaxAgentAdjustRecordQueryParam;
import com.engine.salary.entity.salaryarchive.param.TaxAgentAdjustRecordQueryParam;
import com.engine.salary.entity.salaryarchive.po.SalaryArchiveTaxAgentPO;
import com.engine.salary.entity.taxagent.dto.TaxAgentListDTO;
import com.engine.salary.entity.taxagent.param.TaxAgentQueryParam;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.UserStatusEnum;
import com.engine.salary.enums.auth.AuthFilterTypeEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveTaxAgentAdjustReasonEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.SalaryArchiveTaxAgentService;
import com.engine.salary.service.TaxAgentService;
import com.engine.salary.service.impl.SalaryArchiveTaxAgentServiceImpl;
import com.engine.salary.service.impl.TaxAgentServiceImpl;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.google.common.collect.Lists;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import weaver.hrm.User;

import java.util.*;

/**
 * 薪资档案-个税扣缴义务人
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalaryArchiveTaxAgentWrapper extends Service {

    private SalaryArchiveTaxAgentService getSalaryArchiveTaxAgentService(User user) {
        return (SalaryArchiveTaxAgentService) ServiceUtil.getService(SalaryArchiveTaxAgentServiceImpl.class, user);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return (TaxAgentService) ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

//    
//    private SalaryBatchService salaryBatchService;
//    
//    private ExecutorService taskExecutor;

    /**
     * 获取个税扣缴义务人调整表单
     * 获取调整原因和扣税义务人列表
     *
     * @param salaryArchiveId
     * @return
     */
    public SalaryArchiveTaxAgentFormDTO getTaxAgentForm(Long salaryArchiveId) {
        if (salaryArchiveId == null) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100425, "薪资档案id不能为空"));
        }

        // 调整前
        String adjustBefore = "";
        String adjustReason = "";
        Date effectiveTime = null;
        SalaryArchiveTaxAgentPO adjustBeforePo = getSalaryArchiveTaxAgentService(user).getAdjustBeforeTaxAgent(SalaryArchiveTaxAgentPO.builder().salaryArchiveId(salaryArchiveId).effectiveTime(new Date()).build());
        if (adjustBeforePo != null) {
            TaxAgentPO taxAgent = getTaxAgentService(user).getById(adjustBeforePo.getTaxAgentId());
            if (taxAgent != null) {
                adjustBefore = taxAgent.getName();
            }
            adjustReason = adjustBeforePo.getAdjustReason();
            effectiveTime = adjustBeforePo.getEffectiveTime();
        }


        // 构建表单
        Map<String, Object> form = buildTaxAgentForm(effectiveTime, adjustReason, adjustBefore, null);

        return SalaryArchiveTaxAgentFormDTO.builder()
                .salaryArchiveId(salaryArchiveId)
                .salaryArchiveTaxAgentForm(form)
                .build();
    }

    private Map<String, Object> buildTaxAgentForm(Date effectiveTime, String adjustReason, String adjustBefore, Long adjustAfter) {
        // 个税扣缴义务人下拉列表
        TaxAgentQueryParam param = TaxAgentQueryParam.builder().build();
        param.setFilterType(AuthFilterTypeEnum.ADMIN_DATA);
        Collection<TaxAgentPO> taxAgentList = getTaxAgentService(user).listAuth(param);

        Map<String, Object> map = new HashMap<>();
        map.put("adjustReasonList", SalaryArchiveTaxAgentAdjustReasonEnum.getList());
        map.put("taxAgentList", taxAgentList);
        map.put("effectiveTime", effectiveTime);
        map.put("adjustBefore", adjustBefore);
        map.put("adjustAfter", adjustAfter);
        map.put("adjustReason", adjustReason);
        return map;
    }

    /**
     * 通过薪资档案的个税扣缴义务人id获取个税扣缴义务人调整表单
     *
     * @param salaryArchiveTaxAgentId
     * @return
     */
    public SalaryArchiveTaxAgentFormDTO getTaxAgentFormBySalaryArchiveTaxAgentId(Long salaryArchiveTaxAgentId) {
        if (salaryArchiveTaxAgentId == null) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100489, "薪资档案的个税扣缴义务人id不能为空"));
        }
        SalaryArchiveTaxAgentPO salaryArchiveTaxAgent = getSalaryArchiveTaxAgentService(user).getById(salaryArchiveTaxAgentId);
        if (salaryArchiveTaxAgent == null) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100484, "该薪资档案的个税扣缴义务人的调整记录不存在"));
        }
        // 个税扣缴义务人下拉列表
        Collection<TaxAgentListDTO> taxAgentList = getTaxAgentService(user).findAll();
        // 调整前
        String adjustBefore = "";
        SalaryArchiveTaxAgentPO adjustBeforePo = getSalaryArchiveTaxAgentService(user).getAdjustBeforeTaxAgent(salaryArchiveTaxAgent);

        if (adjustBeforePo != null) {
            Optional<TaxAgentListDTO> optional = taxAgentList.stream().filter(f -> f.getId().equals(adjustBeforePo.getTaxAgentId())).findFirst();
            adjustBefore = optional.isPresent() ? optional.get().getName() : "";
        }

        Date effectiveTime = salaryArchiveTaxAgent.getEffectiveTime();
        String adjustReason = salaryArchiveTaxAgent.getAdjustReason();
        Long adjustAfter = salaryArchiveTaxAgent.getTaxAgentId();

        // 构建表单
        Map<String, Object> taxAgentForm = buildTaxAgentForm(effectiveTime, adjustReason, adjustBefore, adjustAfter);

        return SalaryArchiveTaxAgentFormDTO.builder()
                .salaryArchiveId(salaryArchiveTaxAgent.getSalaryArchiveId())
                .salaryArchiveTaxAgentForm(taxAgentForm)
                .build();
    }

    /**
     * 保存个税扣缴义务人调整
     *
     * @param saveParam
     * @return
     */
    public String saveTaxAgent(SalaryArchiveTaxAgentSaveParam saveParam) {
        return getSalaryArchiveTaxAgentService(user).saveTaxAgent(saveParam);
    }

    /**
     * 删除个税扣缴义务人调整
     *
     * @param salaryArchiveTaxAgentId
     * @return
     */
    public String deleteTaxAgent(Long salaryArchiveTaxAgentId) {
        return getSalaryArchiveTaxAgentService(user).deleteTaxAgent(salaryArchiveTaxAgentId);
    }


    /**
     * 个税扣缴义务人调整记录列表
     *
     * @param queryParam
     * @return
     */
    public PageInfo<TaxAgentAdjustRecordListDTO> adjustRecordList(TaxAgentAdjustRecordQueryParam queryParam) {

        // 个税扣缴义务人
        Collection<TaxAgentListDTO> taxAgentList = getTaxAgentService(user).findAll();
        List<TaxAgentAdjustRecordListDTO> listAll = getSalaryArchiveTaxAgentService(user).taxAgentAdjustRecordList(TaxAgentAdjustRecordQueryParam.builder().build());
        PageInfo<TaxAgentAdjustRecordListDTO> page = getSalaryArchiveTaxAgentService(user).taxAgentAdjustRecordListPage(queryParam);
        List<TaxAgentAdjustRecordListDTO> list = page.getList();
        list.forEach(m -> {
            if (!org.springframework.util.CollectionUtils.isEmpty(listAll)) {
                listAll.removeIf(a -> a.getId().equals(m.getId()));
            }
            Optional<TaxAgentAdjustRecordListDTO> optional = listAll.stream().filter(f -> f.getSalaryArchiveId().equals(m.getSalaryArchiveId())).findFirst();
            m.setAdjustBefore(optional.isPresent() ? optional.get().getAdjustAfter() : "");
            Optional<TaxAgentListDTO> optionalBefore = taxAgentList.stream().filter(t -> t.getId().toString().equals(m.getAdjustBefore())).findFirst();
            m.setAdjustBefore(optionalBefore.isPresent() ? optionalBefore.get().getName() : "");
            Optional<TaxAgentListDTO> optionalAfter = taxAgentList.stream().filter(t -> t.getId().toString().equals(m.getAdjustAfter())).findFirst();
            m.setAdjustAfter(optionalAfter.isPresent() ? optionalAfter.get().getName() : "");

            m.setEmployeeStatus(UserStatusEnum.getDefaultLabelByValue(Integer.parseInt(m.getEmployeeStatus())));

            m.setAdjustReason(SalaryArchiveTaxAgentAdjustReasonEnum.getDefaultLabelByValue(m.getAdjustReason()));
        });

        return page;
    }

    /**
     * 单个档案的个税扣缴义务人调整记录列表
     *
     * @param queryParam
     * @return
     */
    public PageInfo<SingleTaxAgentAdjustRecordListDTO> singleTaxAgentAdjustRecordList(SingleTaxAgentAdjustRecordQueryParam queryParam) {
        if (queryParam.getSalaryArchiveId() == null) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100425, "薪资档案id不能为空"));
        }

        TaxAgentAdjustRecordQueryParam adjustRecordQueryParam = new TaxAgentAdjustRecordQueryParam();
        BeanUtils.copyProperties(queryParam, adjustRecordQueryParam);
        PageInfo<TaxAgentAdjustRecordListDTO> page = getSalaryArchiveTaxAgentService(user).taxAgentAdjustRecordListPage(adjustRecordQueryParam);

        // 个税扣缴义务人
        Collection<TaxAgentListDTO> taxAgentList = getTaxAgentService(user).findAll();
        List<TaxAgentAdjustRecordListDTO> listAll = getSalaryArchiveTaxAgentService(user).taxAgentAdjustRecordList(TaxAgentAdjustRecordQueryParam.builder().build());
        List<TaxAgentAdjustRecordListDTO> list = page.getList();
        List<SingleTaxAgentAdjustRecordListDTO> resultList = Lists.newArrayList();
        list.forEach(m -> {
            if (!org.springframework.util.CollectionUtils.isEmpty(listAll)) {
                listAll.removeIf(a -> a.getId().equals(m.getId()));
            }
            Optional<TaxAgentAdjustRecordListDTO> optional = listAll.stream().filter(f -> f.getSalaryArchiveId().equals(m.getSalaryArchiveId())).findFirst();
            m.setAdjustBefore(optional.isPresent() ? optional.get().getAdjustAfter() : "");
            Optional<TaxAgentListDTO> optionalBefore = taxAgentList.stream().filter(t -> t.getId().toString().equals(m.getAdjustBefore())).findFirst();
            m.setAdjustBefore(optionalBefore.isPresent() ? optionalBefore.get().getName() : "");
            Optional<TaxAgentListDTO> optionalAfter = taxAgentList.stream().filter(t -> t.getId().toString().equals(m.getAdjustAfter())).findFirst();
            m.setAdjustAfter(optionalAfter.isPresent() ? optionalAfter.get().getName() : "");

            m.setAdjustReason(SalaryArchiveTaxAgentAdjustReasonEnum.getDefaultLabelByValue(m.getAdjustReason()));

            SingleTaxAgentAdjustRecordListDTO singleTaxAgentAdjustRecordList = new SingleTaxAgentAdjustRecordListDTO();
            BeanUtils.copyProperties(m, singleTaxAgentAdjustRecordList);
            resultList.add(singleTaxAgentAdjustRecordList);
        });
        // 获取当前已生效
        SalaryArchiveTaxAgentPO salaryArchiveTaxAgent = getSalaryArchiveTaxAgentService(user).getEffectiveTaxAgent(queryParam.getSalaryArchiveId());
        Date effectiveDate = (salaryArchiveTaxAgent == null ? null : salaryArchiveTaxAgent.getEffectiveTime());

        // 行记录按钮权限控制
        for (int i = 0; i < resultList.size(); i++) {
            SingleTaxAgentAdjustRecordListDTO singleTaxAgentAdjustRecord = resultList.get(i);
            if (effectiveDate != null && singleTaxAgentAdjustRecord.getEffectiveTime().before(effectiveDate)) {
                singleTaxAgentAdjustRecord.setCanOperator(Boolean.FALSE);
            } else {
                singleTaxAgentAdjustRecord.setCanOperator(Boolean.TRUE);
            }
        }
        PageInfo<SingleTaxAgentAdjustRecordListDTO> listPage = new PageInfo<SingleTaxAgentAdjustRecordListDTO>(resultList, SingleTaxAgentAdjustRecordListDTO.class);
        listPage.setTotal(page.getTotal());
        listPage.setPageNum(page.getPageNum());
        listPage.setPageSize(page.getPageSize());

        return listPage;
    }

    /**
     * 导出个税扣缴义务人调整记录列表
     *
     * @param queryParam
     * @return
     */
    public XSSFWorkbook exportAdjustRecordList(TaxAgentAdjustRecordQueryParam queryParam) {
        return getSalaryArchiveTaxAgentService(user).exportAdjustRecordList(queryParam);
    }


}
